package com.magina.machine.controller;


import com.magina.machine.model.ApproveEvent;
import com.magina.machine.model.ApproveStatus;
import com.magina.machine.model.DemoClass;
import org.assertj.core.util.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.service.StateMachineService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.UUID;

@RestController
@RequestMapping("/approve")
public class ApproveStatusMachineController {

    private Logger log = LoggerFactory.getLogger(getClass());

    private DemoClass demoClass;

    @Autowired
    @Qualifier("approveMachineService")
    private StateMachineService<ApproveStatus, ApproveEvent> approveMachineService;


    //执行顺序:

    /**
     *  先init machine
     *  =>ApproveRedisPersister.read() 读取是否有持久化的machine
     *  =>listener.transition()方法读取状态
     *  =>ApproveRedisPersister.preStateChange()预处理 state修改事件
     *  =>ApproveRedisPersister.write()
     *  =>listener.stateContext()
     *
     */
    @GetMapping("/testApproveDraftState")
    public void testApproveDraftState() throws InterruptedException {
        String UUID_DEMO  = UUID.randomUUID().toString();
         demoClass = DemoClass.builder()
                .uuid(UUID_DEMO)
                .createDate(new Date())
                .name("yes class!")
                .status(ApproveStatus.DRAFT.name())
                .build();
        log.info("当前线程: {} ,初始化业务数据: {}",Thread.currentThread().getName(),demoClass);
        StateMachine<ApproveStatus, ApproveEvent> stateMachine = approveMachineService.acquireStateMachine(demoClass.getUuid());
        stateMachine.start();
        stateMachine.sendEvent(MessageBuilder.withPayload(ApproveEvent.LAUNCH).setHeader("demoClass",demoClass).build());
        log.info("当前线程: {} ,当前状态: {}",Thread.currentThread().getName(),stateMachine.getState().getId());
    }

    @GetMapping("/testApproveState")
    public void testApproveState() throws InterruptedException {
        //此处获取得stateMachine 都是被内存持久化了.根据id获取的都是同一个statemachine(不需要手动的persister和restore)
        //如何避免项目重启丢失持久化的machine.uuid对应的业务数据存到了redis,在approveRedisPersister里面做了判定read hit
        StateMachine<ApproveStatus, ApproveEvent> stateMachine = approveMachineService.acquireStateMachine(demoClass.getUuid());
        stateMachine.sendEvent(MessageBuilder.createMessage(ApproveEvent.APPROVE,new MessageHeaders(Maps.newHashMap("demoClass",demoClass))));
        log.info("当前线程: {} ,当前状态: {}",Thread.currentThread().getName(),stateMachine.getState().getId());
    }

    @GetMapping("/testApproveCompleteState")
    public void testApproveCompleteState() throws InterruptedException {
        StateMachine<ApproveStatus, ApproveEvent> stateMachine = approveMachineService.acquireStateMachine("8bf626b4-34c4-46cb-b377-e19578e0793c");
        stateMachine.sendEvent(MessageBuilder.createMessage(ApproveEvent.COMPLETE,new MessageHeaders(Maps.newHashMap("demoClass",demoClass))));
        log.info("当前线程: {} ,当前状态: {}",Thread.currentThread().getName(),stateMachine.getState().getId());
    }

    //未解决的问题:
    // 1: 没有依赖redis persister machine.而是 persister uuid 去构建machine.如果redis挂了,则数据脏乱
    // 2:没有配置的流程 例如:draft->on_approval 不会进去machine逻辑,这时候需要系统提示




}
